<?php
/**
 * Created by paperphp
 * User: 22071
 * Date: 2019/6/28
 * Email: <zhendongdong@foxmail.com>
 */

namespace paper\captcha;

use paper\App;
use paper\Container;
use paper\exception\ResponseException;
use paper\Response;

class Captcha
{
    private $container;
    private $width;
    private $height;
    private $im;
    private $strColor;
    private $code;
    private $minFontSize;
    private $maxFontSize;

    function __construct($width = 140, $height = 50, $min_fontSize = 24, $max_fontSize = 26)
    {
        $this->container   = App::getInstance();
        $this->width       = $width;
        $this->height      = $height;
        $this->minFontSize = $min_fontSize;
        $this->maxFontSize = $max_fontSize;
        $this->create();
    }

    private function setCode($code)
    {
        $this->code = $code;
    }

    protected function code()
    {
        $str  = "0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVW";
        $max  = strlen($str) - 1;
        $code = '';
        for ($i = 0; $i < 5; $i++) {
            $code .= $str{rand(0, $max)};
        }
        $this->container->session->set("captcha", $code);
        return $code;
    }

    public function validate($input)
    {
        $input = trim(strval($input));
        if (!$input) {
            return false;
        }
        if (!($captcha = $this->container->session->get("captcha"))) {
            return false;
        }
        if (strcmp($input, $captcha) != 0) {
            return false;
        }
        $this->container->session->destroy("captcha");
        return true;
    }

    private function create()
    {
        $this->im = imagecreate($this->width, $this->height);//创建画布
        imagecolorallocate($this->im, 200, 200, 200);//为画布添加颜色

        $captcha_code        = strval($this->code ?: $this->code());
        $captcha_code_length = strlen($captcha_code);

        for ($i = 0; $i < $captcha_code_length; $i++) {
            $this->strColor = imagecolorallocate($this->im, rand(0, 100), rand(0, 100), rand(0, 100));
            $fontSize       = rand($this->maxFontSize, $this->maxFontSize);
            $fontPath       = __DIR__ . DIRECTORY_SEPARATOR . 'mingliu.ttc';
            $angle          = rand(-20, 20);
            $x              = $this->width / $captcha_code_length * $i + rand(5, 10);
            $y              = rand(30, 40);
            imagettftext($this->im, $fontSize, $angle, $x, $y, $this->strColor, $fontPath, $captcha_code{$i});
        }
        for ($i = 0; $i < 200; $i++) {//循环输出200个像素点
            $this->strColor = imagecolorallocate($this->im, rand(0, 255), rand(0, 255), rand(0, 255));
            imagesetpixel($this->im, rand(0, $this->width), rand(0, $this->height), $this->strColor);
        }
    }

    /**
     * @throws ResponseException
     */
    public function show()
    {
        $header   = ["Content-Type" => "image/png"];
        $response = Response::create(function () {
            imagepng($this->im);//生成图像
            imagedestroy($this->im);//销毁图像释放内存
        }, 200, null, $header);
        throw new ResponseException($response);
    }
}